﻿// This source file is part of WallpaperControl, a tool for automatic changing 
// of the desktop wallpaper.
// 
// Visit http://wpcontrol.sourceforge.net/ for more.
//
// Copyright (c) 2014 nscrolldev
//
// Licensed under the GPLv2.
// See http://www.gnu.org/licenses/gpl-2.0.html for details.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

using System;
using System.Windows.Forms;
using System.Drawing;

namespace WallpaperControl
{
    /// <summary>
    /// Represents the application running in background.
    /// </summary>
    class TrayApp : IDisposable
    {
        /// <summary>
        /// Indicates whether the TrayApp is currently active.
        /// </summary>
        private bool _active;

        /// <summary>
        /// Get or sets whether the TrayApp is currently active.
        /// </summary>
        /// <value>True if TrayApp is active, false otherwise.</value>
        internal bool Active
        {
            get
            {
                return this._active;
            }
            set
            {
                this._active = value;
            }
        }

        /// <summary>
        /// The icon that appears in system tray.
        /// </summary>
        private NotifyIcon _trayIcon;
        /// <summary>
        /// Gets or sets the icon displayed in System Tray.
        /// </summary>
        internal NotifyIcon TrayIcon
        {
            get
            {
                return this._trayIcon;
            }
            set
            {
                this._trayIcon = value;
            }
        }
        /// <summary>
        /// The context menu shown when the user right-clicks on the trayicon.
        /// </summary>
        private ContextMenu _trayMenu = new ContextMenu();
        internal ContextMenu TrayMenu
        {
            get
            {
                if (this.Active)
                {
                    return this._trayMenu;
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
            set
            {
                this._trayMenu = value;
            }
        }

        private MenuItem _contextControlPanel = new MenuItem();
        internal MenuItem ContextControlPanel
        {
            get
            {
                if (this.Active)
                {
                    return this._contextControlPanel;
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
            set
            {
                this._contextControlPanel = value;
            }
        }
        private MenuItem _contextSession = new MenuItem();
        internal MenuItem ContextSession
        {
            get
            {
                if (this.Active)
                {
                    return this._contextSession;
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
            set
            {
                this._contextSession = value;
            }
        }
        private MenuItem _contextPreviousWallpaper = new MenuItem();
        internal MenuItem ContextPreviousWallpaper
        {
            get
            {
                if (this.Active)
                {
                    return this._contextPreviousWallpaper;
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
            set
            {
                this._contextPreviousWallpaper = value;
            }
        }
        private MenuItem _contextNextWallpaper = new MenuItem();
        internal MenuItem ContextNextWallpaper
        {
            get
            {
                if (this.Active)
                {
                    return this._contextNextWallpaper;
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
            set
            {
                this._contextNextWallpaper = value;
            }
        }
        private MenuItem _contextExit = new MenuItem();
        internal MenuItem ContextExit
        {
            get
            {
                if (this.Active)
                {
                    return this._contextExit;
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
            set
            {
                this._contextExit = value;
            }
        }

        /// <summary>
        /// Enters the TrayApp. The icon with the context menu is shown.
        /// </summary>
        internal void Enter()
        {
            // Create with context menu
            CreateTrayIcon();
            CreateContextMenu();
            // Show balloon tip if requested
            if (!Program.Configuration.StartWithControlPanel)
            {
                if (Program.Configuration.RunningInfo)
                    TrayIcon.ShowBalloonTip(2000, "WallpaperControl", Program.Lang.GetString("Tip_MinimizedDesc"), ToolTipIcon.Info);
            }
        }

        /// <summary>
        /// Clean up resources
        /// </summary>
        public void Dispose()
        {
            if (!this.Active)
            {
                if (this.TrayIcon != null)
                {
                    this.TrayIcon.Dispose();
                    this.ContextControlPanel.Dispose();
                    this.ContextExit.Dispose();
                    this.ContextNextWallpaper.Dispose();
                    this.ContextPreviousWallpaper.Dispose();
                    this.ContextSession.Dispose();
                    this.TrayMenu.Dispose();
                    this._contextNextWallpaper.Dispose();
                    this._contextPreviousWallpaper.Dispose();
                    this._contextSession.Dispose();
                    this._contextExit.Dispose();
                    this._contextControlPanel.Dispose();
                    this._trayMenu.Dispose();
                    this._trayIcon.Dispose();
                }
                GC.SuppressFinalize(this);
            }
        }

        /// <summary>
        /// Exits the TrayApp. Removes the icon from the system tray.
        /// </summary>
        internal void Exit()
        {
            // Indicate that TrayApp is inactive
            this.Active = false;
            // Hide icon
            this.TrayIcon.Visible = false;
        }

        /// <summary>
        /// Creates the notify icon in the system tray.
        /// </summary>
        private void CreateTrayIcon()
        {
            // Indicate that TrayApp is active
            this.Active = true;

            TrayIcon = new NotifyIcon();
            // Set icon
            TrayIcon.Icon = WallpaperControl.Properties.Resources.icon;
            // Text
            TrayIcon.Text = "WallpaperControl";
            // Open ControlPanel on doubleclick
            TrayIcon.DoubleClick += new EventHandler(TrayIcon_DoubleClick);
            // Show icon
            TrayIcon.Visible = true;
        } 

        /// <summary>
        /// Adds the context menu to the tray icon.
        /// </summary>
        private void CreateContextMenu()
        {    
            // Add items with event in correct order
            this.ContextControlPanel.Text = Program.Lang.GetString("Action_ShowControlPanelText"); //System.Globalization.CultureInfo.CurrentCulture
            this.ContextControlPanel.Click += new EventHandler(itemControlPanel_Click);
            this.TrayMenu.MenuItems.Add(this.ContextControlPanel);

            this.ContextSession.Text = Program.Lang.GetString("Action_ActivateText");
            this.ContextSession.Click += new EventHandler(itemSession_Click);
            this.TrayMenu.MenuItems.Add(this.ContextSession);

            this.ContextNextWallpaper.Text = Program.Lang.GetString("Action_NextWallpaperText");
            this.ContextNextWallpaper.Click += new EventHandler(itemNext_Click);
            this.TrayMenu.MenuItems.Add(this.ContextNextWallpaper);

            this.ContextPreviousWallpaper.Text = Program.Lang.GetString("Action_PreviousWallpaperText");
            this.ContextPreviousWallpaper.Click += new EventHandler(itemPrevious_Click);
            this.TrayMenu.MenuItems.Add(this.ContextPreviousWallpaper);

            this.ContextExit.Text = Program.Lang.GetString("Action_ExitText");
            this.ContextExit.Click += new EventHandler(itemExit_Click);
            this.TrayMenu.MenuItems.Add(this.ContextExit);

            // Add this menu to icon
            TrayIcon.ContextMenu = this.TrayMenu;
        }

        #region EventHandlers
        private void TrayIcon_DoubleClick(object sender, EventArgs e)
        {
            Program.EnterControlPanel();
            Program.ControlPanel.RestoreValues();
        }

        private void itemControlPanel_Click(object sender, EventArgs e)
        {
            Program.EnterControlPanel();
            Program.ControlPanel.RestoreValues();
        }

        private void itemNext_Click(object sender, EventArgs e)
        {
            WallpaperManager.Instance.SetNextWallpaper();
        }

        private void itemPrevious_Click(object sender, EventArgs e)
        {
            WallpaperManager.Instance.SetPreviousWallpaper();
        }

        private void itemExit_Click(object sender, EventArgs e)
        {
            Program.CfgFileManager.SaveSessionFile();
            Program.CfgFileManager.SaveConditionFile();
            this.Exit();
            Program.ControlPanel.Close();
            Application.Exit();
        }

        private void itemSession_Click(object sender, EventArgs e)
        {
            if (!Program.CurrentSession.IsActive)
            {
                Program.CurrentSession.Start();
            }
            else
            {
                Program.CurrentSession.Stop();
            }
            Program.ControlPanel.UpdateSchedule();
        }
        #endregion
    }
}
